package com.ssy.lingxi.member.merchant.serviceimpl.base;

import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.common.model.dto.MemberLrcCacheDTO;
import com.ssy.lingxi.common.utils.DateTimeUtil;
import com.ssy.lingxi.component.redis.service.IRedisUtils;
import com.ssy.lingxi.member.merchant.entity.MemberCreditDO;
import com.ssy.lingxi.member.merchant.entity.MemberLevelRightDO;
import com.ssy.lingxi.member.merchant.entity.MemberRelationDO;
import com.ssy.lingxi.member.merchant.api.constant.MemberRelationTypeEnum;
import com.ssy.lingxi.member.merchant.repository.MemberRelationRepository;
import com.ssy.lingxi.member.merchant.service.base.IBaseMemberLrcCacheService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 平台会员等级、权益、信用信息缓存接口实现类
 * @author 万宁
 * @version 2.0.0
 * @date 2020-11-23
 */
@Service
public class BaseMemberLrcCacheServiceImpl implements IBaseMemberLrcCacheService {
    @Resource
    private IRedisUtils redisUtils;

    @Resource
    private MemberRelationRepository relationRepository;

    /**
     * 缓存的Key
     * @param memberId 会员Id
     * @param roleId 角色Id
     * @return Key字符串
     */
    private String getCacheKey(Long memberId, Long roleId) {
        return Constants.MEMBER_LRC_PREFIX.concat(Constants.MEMBER_LRC_SPLIT).concat(String.valueOf(memberId)).concat(Constants.MEMBER_LRC_SPLIT).concat(String.valueOf(roleId));
    }

    /**
     * 系统启动完成后，初始化所有平台会员的等级、权益、信用信息
     */
    @Async
    @Override
    public void initMemberLrcCache() {
        List<MemberRelationDO> relationList = relationRepository.findAllByRelType(MemberRelationTypeEnum.PLATFORM.getCode());
        if(CollectionUtils.isEmpty(relationList)) {
            return;
        }

        Map<String, Object> cacheMap = new HashMap<>();
        for (MemberRelationDO relationDO : relationList) {
            String cacheKey = getCacheKey(relationDO.getSubMemberId(), relationDO.getSubRoleId());
            MemberLrcCacheDTO cacheDTO = new MemberLrcCacheDTO();
            MemberLevelRightDO levelRightDO = relationDO.getLevelRight();
            if(levelRightDO != null) {
                cacheDTO.setLevel(levelRightDO.getLevel());
                cacheDTO.setLevelTag(levelRightDO.getLevelTag());
                cacheDTO.setScore(levelRightDO.getScore());
                cacheDTO.setSumReturnMoney(levelRightDO.getSumReturnMoney().doubleValue());
                cacheDTO.setSumPoint(levelRightDO.getSumPoint());
                cacheDTO.setCurrentPoint(levelRightDO.getCurrentPoint());
                cacheDTO.setSumUsedPoint(levelRightDO.getSumUsedPoint());
            }

            MemberCreditDO creditDO = relationDO.getCredit();
            if(creditDO != null) {
                cacheDTO.setCreditPoint(creditDO.getCreditPoint());
                cacheDTO.setTradeCommentPoint(creditDO.getTradeCommentPoint());
                cacheDTO.setAfterSaleCommentPoint(creditDO.getAfterSaleCommentPoint());
                cacheDTO.setComplainPoint(creditDO.getComplainPoint());
                cacheDTO.setRegisterYearsPoint(creditDO.getRegisterYearsPoint());
                cacheDTO.setAvgTradeCommentStar(creditDO.getAvgTradeCommentStar());
            }

            cacheDTO.setRegisterYears(DateTimeUtil.diffYears(relationDO.getCreateTime(), LocalDateTime.now()));

            cacheMap.put(cacheKey, cacheDTO);
        }

        redisUtils.setBatch(cacheMap, Constants.REDIS_USER_INDEX);
    }

    /**
     * 获取缓存中的平台会员等级、权益、信用信息
     * @param memberId 会员Id
     * @param roleId 角色Id
     * @return 缓存信息实体
     */
    @Override
    public MemberLrcCacheDTO getLrc(Long memberId, Long roleId) {
        String cacheKey = getCacheKey(memberId, roleId);
        MemberLrcCacheDTO cacheDTO = redisUtils.get(cacheKey, Constants.REDIS_USER_INDEX, MemberLrcCacheDTO.class);
        if(cacheDTO == null) {
            cacheDTO = new MemberLrcCacheDTO();
        }

        return cacheDTO;
    }

    /**
     * 缓存会员的等级、权益、信用信息
     *  @param memberId 会员Id
     * @param roleId   角色Id
     * @param cacheDTO 等级、权益、信用信息
     */
    @Override
    public void setLrc(Long memberId, Long roleId, MemberLrcCacheDTO cacheDTO) {
        String cacheKey = getCacheKey(memberId, roleId);
        redisUtils.set(cacheKey, cacheDTO, Constants.REDIS_USER_INDEX);
    }

    /**
     * 缓存会员等级信息
     * @param memberId 会员Id
     * @param roleId   角色Id
     * @param level    会员等级
     * @param levelTag 等级名称
     * @param score    等级积分
     */
    @Override
    public void cacheMemberLevel(Long memberId, Long roleId, Integer level, String levelTag, Integer score) {
        MemberLrcCacheDTO cacheDTO = getLrc(memberId, roleId);
        cacheDTO.setScore(score);
        cacheDTO.setLevel(level);
        cacheDTO.setLevelTag(levelTag);
        setLrc(memberId, roleId, cacheDTO);
    }

    /**
     * 缓存会员权益信息
     *
     * @param memberId       会员Id
     * @param roleId         角色Id
     * @param sumReturnMoney 累计返现金额
     * @param sumPoint       累计获得的权益积分
     * @param currentPoint   当前可用的权益积分 = 累计获得的权益积分 - 累计已用权益积分
     * @param sumUsedPoint   累计使用的权益积分
     */
    @Override
    public void cacheMemberRight(Long memberId, Long roleId, Double sumReturnMoney, Integer sumPoint, Integer currentPoint, Integer sumUsedPoint) {
        MemberLrcCacheDTO cacheDTO = getLrc(memberId, roleId);
        cacheDTO.setSumReturnMoney(sumReturnMoney);
        cacheDTO.setSumPoint(sumPoint);
        cacheDTO.setCurrentPoint(currentPoint);
        cacheDTO.setSumUsedPoint(sumUsedPoint);
        setLrc(memberId, roleId, cacheDTO);
    }

    /**
     * 缓存会员信用信息
     *
     * @param memberId              会员Id
     * @param roleId                角色Id
     * @param creditPoint           信用积分 = 交易评价积分 + 售后评价积分 + 投诉扣分 + 入驻年数积分
     * @param tradeCommentPoint     交易评价信用积分
     * @param afterSaleCommentPoint 售后评价信用积分
     * @param complainPoint         投诉扣分
     * @param registerYearsPoint    入驻年数积分
     * @param avgTradeCommentStar   交易评价平均星级（总体满意度）
     * @param registerYears         注册年数
     */
    @Override
    public void cacheMemberCredit(Long memberId, Long roleId, Integer creditPoint, Integer tradeCommentPoint, Integer afterSaleCommentPoint, Integer complainPoint, Integer registerYearsPoint, Integer avgTradeCommentStar, Integer registerYears) {
        MemberLrcCacheDTO cacheDTO = getLrc(memberId, roleId);
        cacheDTO.setCreditPoint(creditPoint);
        cacheDTO.setTradeCommentPoint(tradeCommentPoint);
        cacheDTO.setAfterSaleCommentPoint(afterSaleCommentPoint);
        cacheDTO.setComplainPoint(complainPoint);
        cacheDTO.setRegisterYearsPoint(registerYearsPoint);
        cacheDTO.setAvgTradeCommentStar(avgTradeCommentStar);
        cacheDTO.setRegisterYears(registerYears);
        setLrc(memberId, roleId, cacheDTO);
    }


}
